﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Xml;
using CoDbObject;

namespace Colligate.DataSource.DriverTraining
{
    public abstract class BaseDataTree
    {
        #region 类型定义
        public enum DataTypeCategory
        {
            SET_DATA_LIST,
            GET_DATA_LIST,
            TRANSFORM_LIST
        }
        #endregion

        #region 属性定义
        protected string _baseNameSpace = "";
        protected string _curNodeName = "";
        protected string[,] _subDataTreeList = null;

        //private bool[] _initedDataTypeList = new bool[3] { false, false, false };
        //protected string[][] _dataTypeList = new string[3][] { null, null, null };
        private Dictionary<DataTypeCategory, bool> _initedDataTypeList = new Dictionary<DataTypeCategory, bool>();
        protected Dictionary<DataTypeCategory, string[]> _dataTypeList = new Dictionary<DataTypeCategory, string[]>();

        protected string _taskGuid;
        protected IDataSourceLayer _dbLayer;
        protected BaseLegoModule _dataDefine;
        protected IDataService _dataService;

        public string[,] SubDataTreeList
        {
            get { return _subDataTreeList; }
            set { _subDataTreeList = value; }
        }
        public IDataService DataService
        {
            get { return _dataService; }
            set { _dataService = value; }
        }
        #endregion

        public BaseDataTree(string taskGuid, IDataSourceLayer dataLayer, IDataService dataService)
        {
            _baseNameSpace = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Namespace;
            _taskGuid = taskGuid;
            _dbLayer = dataLayer;
            _dataService = dataService;
            _initedDataTypeList.Add(DataTypeCategory.GET_DATA_LIST, false);
            _initedDataTypeList.Add(DataTypeCategory.SET_DATA_LIST, false);
            _initedDataTypeList.Add(DataTypeCategory.TRANSFORM_LIST, false);
            _dataTypeList.Add(DataTypeCategory.GET_DATA_LIST, new string[] { });
            _dataTypeList.Add(DataTypeCategory.SET_DATA_LIST, new string[] { });
            _dataTypeList.Add(DataTypeCategory.TRANSFORM_LIST, new string[] { });
        }

        public string[] DataTypeList(DataTypeCategory typeCategory)
        {
            //int typeCategory = (int)listCategory;
            if(!_initedDataTypeList[typeCategory])
            {
                ArrayList typeList = new ArrayList();
                if (_dataTypeList[typeCategory] != null)
                {
                    foreach (string subType in _dataTypeList[typeCategory])
                    {
                        typeList.Add(subType);
                    }
                }
                if (_subDataTreeList != null)
                {
                    for (int i = 0; i < _subDataTreeList.GetLength(0); i++)
                    {
                        //string subNodeName = ((_curNodeName == "") ? "DataBranch_" : "DataNode_" + _curNodeName) + _subDataTreeList[i, 1];
                        string subNodeName = "DataNode_" + _curNodeName + _subDataTreeList[i, 1];
                        BaseDataTree subTree = UtilityInstance.GetInstance(subNodeName, _taskGuid, _dbLayer, _dataService) as BaseDataTree;
                        string[] subList = subTree.DataTypeList(typeCategory);

                        if (subList != null)
                        {
                            foreach (string subType in subList)
                            {
                                typeList.Add(subType);
                            }
                        }
                    }
                }
                _dataTypeList[typeCategory] = (string[])typeList.ToArray(typeof(string));
                _initedDataTypeList[typeCategory] = true;
            }
            return _dataTypeList[typeCategory];
        }

        #region 数据存取
        public virtual int SetData(OUDataInfo UserInfo, string DataGuid, string DataType, XmlNode XmlData)
        {
            BaseDataTree subTree = GetDataNodeByDataType(DataType);
            return subTree.SetData(UserInfo, DataGuid, DataType, XmlData);
        }
        public virtual int DeleteData(OUDataInfo UserInfo, string DataGuid, string DataType)
        {
            BaseDataTree subTree = GetDataNodeByDataType(DataType);
            return subTree.DeleteData(UserInfo, DataGuid, DataType);
        }
        public virtual XmlNode GetData(OUDataInfo UserInfo, string DataGuid, string DataType)
        {
            BaseDataTree subTree = GetDataNodeByDataType(DataType);
            return subTree.GetData(UserInfo,DataGuid,DataType);
        }
        public virtual XmlNode TransformData(OUDataInfo UserInfo, string DataType, XmlNode XmlParam)
        {
            BaseDataTree subTree = GetDataNodeByDataType(DataType);
            return subTree.TransformData(UserInfo, DataType, XmlParam);
        }
        #endregion

        private BaseDataTree GetDataNodeByDataType(string DataType)
        {
            //string branchCode = UtilityInstance.ExtractWord(DataType, 0);
            //string nodeCode = UtilityInstance.ExtractWord(DataType, 1);
            //string matchCode = (_curNodeName == "") ? branchCode : nodeCode;
            //string subNodeName = "";

            int curNodeLevel = UtilityInstance.GetWordsCount(_curNodeName);
            string matchCode = UtilityInstance.ExtractWord(DataType, curNodeLevel);
            string subNodeName = "";
            
            for (int i = 0; i < _subDataTreeList.GetLength(0); i++)
            {
                if( matchCode == _subDataTreeList[i,0])
                {
                    subNodeName = _subDataTreeList[i, 1];
                    break;
                }
            }
            subNodeName = "DataNode_" + _curNodeName + subNodeName;
            BaseDataTree subTree = UtilityInstance.GetInstance(subNodeName, _taskGuid, _dbLayer, _dataService) as BaseDataTree;
            //subTree.DataLayer = _dbLayer;
            return subTree;
        }

        protected string GetNodeName(string nodeFullName)
        {
            return nodeFullName.Substring(_baseNameSpace.Length).Replace(".", "");
        }
    }
}
